﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Globalization;

namespace Financeiro.Dados
{
    public class ContasDAO
    {
        private static string connectionSettings = ConfigurationManager.ConnectionStrings["ERP_FinanceiroConnectionString"].ConnectionString;

        //Retorna todas as contas que são do tipo: 0 - "Cobrança", 1 - "Débitos".
        public static DataTable listContas(int tipo)
        {
            //SQL Query para obter a lista de Contas.
            string query_string = "";
            if (tipo == 0)
            {
                query_string = "SELECT * FROM Conta WHERE id_atendimento IS NOT NULL";
            }
            else
            {
                query_string = "SELECT * FROM Conta WHERE id_atendimento IS NULL";
            }
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(command);
                DataSet data_set = new DataSet();
                data_adapter.Fill(data_set, "Conta");
                connection.Close();

                //Criação do DataTable com os dados extraídos do banco e uma coluna extra: String do Status.
                DataTable data_table = data_set.Tables["Conta"];
                DataColumn status_string;
                status_string = new DataColumn();
                status_string.DataType = System.Type.GetType("System.String");
                status_string.AutoIncrement = false;
                status_string.ColumnName = "status_string";
                status_string.ReadOnly = false;
                status_string.Unique = false;
                data_table.Columns.Add(status_string);
                foreach (DataRow row in data_table.Rows)
                {
                    int status = Convert.ToInt32(row["status"]);
                    // Efetuando a troca de número para texto.
                    if (status == 1)
                    { row["status_string"] = "Pago"; }
                    else if (status == 2)
                    { row["status_string"] = "Emitida"; }
                    else
                    { row["status_string"] = "Pendente"; }
                }

                return data_table;
            }
            catch (Exception ex)
            {
                throw new Exception("Erro no acesso aos dados." + ex.Message);
            }
        }

        //Retorna as contas de determinado tipo e numa faixa de data de lançamento
        public static DataTable listContas(int tipo, DateTime dtInicio, DateTime dtFinal)
        {
            //SQL Query para obter a lista de Contas.
            string query_string = "SELECT * FROM Conta WHERE id_atendimento IS ";
            if (tipo == 0)
            {
                query_string += " NOT";
            }
            query_string += " NULL AND data_pagamento > @dtInicio AND data_pagamento < @dtFinal";

            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection conn = new SqlConnection(connectionSettings);
                SqlCommand cmd = new SqlCommand(query_string, conn);
                cmd.Parameters.Add("@dtInicio", SqlDbType.DateTime);
                cmd.Parameters["@dtInicio"].Value = dtInicio;
                cmd.Parameters.Add("@dtFinal", SqlDbType.DateTime);
                cmd.Parameters["@dtFinal"].Value = dtFinal;
                cmd.CommandType = CommandType.Text;

                //Executa a SQL Query.
                conn.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(cmd);
                DataSet data_set = new DataSet();
                data_adapter.Fill(data_set, "Conta");
                conn.Close();

                //Criação do DataTable com os dados extraídos do banco e uma coluna extra: String do Status.
                DataTable data_table = data_set.Tables["Conta"];
                DataColumn status_string;
                status_string = new DataColumn();
                status_string.DataType = System.Type.GetType("System.String");
                status_string.AutoIncrement = false;
                status_string.ColumnName = "status_string";
                status_string.ReadOnly = false;
                status_string.Unique = false;
                data_table.Columns.Add(status_string);
                foreach (DataRow row in data_table.Rows)
                {
                    int status = Convert.ToInt32(row["status"]);
                    // Efetuando a troca de número para texto.
                    if (status == 1)
                    { row["status_string"] = "Pago"; }
                    else if (status == 2)
                    { row["status_string"] = "Emitida"; }
                    else
                    { row["status_string"] = "Pendente"; }
                }

                return data_table;
            }
            catch (Exception ex)
            {
                throw new Exception("Erro no acesso aos dados." + ex.Message);
            }
        }

        public static DataTable retrieveConta(int id_conta)
        {
            DataSet data_set = new DataSet();
            //SQL Query para obter uma Conta de acordo com o ID fornecido.
            string query_string = "SELECT * FROM Conta WHERE id_conta = @id_conta";
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@id_conta", SqlDbType.Int);
                command.Parameters["@id_conta"].Value = id_conta;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(command);
                data_adapter.Fill(data_set, "Conta");
                connection.Close();

                //Criação da DataTable com os dados extraídos do banco.
                DataTable data_table = data_set.Tables["Conta"];

                return data_table;
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro no banco: " + ex.Message);
            }

        }

		public static int retrieveIdCliente(int id_conta)
		{
			//SQL Query para obter apenas o ID do Cliente.
			string query_string = "SELECT TOP 1 id_cliente from Conta WHERE id_conta = @id_conta";
			try
			{
				int id = 0;

				//Define os parâmetros e cria a conexão.
				SqlConnection connection = new SqlConnection(connectionSettings);
				SqlCommand command = new SqlCommand(query_string, connection);
				command.Parameters.Add("@id_conta", SqlDbType.Int);
				command.Parameters["@id_conta"].Value = id_conta;
				command.CommandType = CommandType.Text;

				//Executa a SQL Query.
				if (!(command.ExecuteScalar() is DBNull))
				{
					id = (int)command.ExecuteScalar();
				}

				return id;
			}
			catch (Exception ex)
			{
				throw new Exception("Ocorreu um erro no banco: " + ex.Message);
			}
		}

        public static int retrieveAtendimento(int id_conta)
        {
            DataSet data_set = new DataSet();
            //SQL Query para obter apenas o ID de Atendimento.
            string query_string = "SELECT id_atendimento FROM Conta WHERE id_conta = @id_conta";
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@id_conta", SqlDbType.Int);
                command.Parameters["@id_conta"].Value = id_conta;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(command);
                data_adapter.Fill(data_set, "Conta");
                connection.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro no banco: " + ex.Message);
            }
            try
            {
                //Criação da DataTable com os dados extraídos do banco.
                DataTable data_table = data_set.Tables["Conta"];
                DataRow row = data_table.Rows[0];
                int id_atendimento = Convert.ToInt32(row["id_atendimento"]);
                return id_atendimento;
            }
            catch
            {
                return 0;
            }
        }

        public static string retrieveDataEmissao(int id_conta)
        {
            DataSet data_set = new DataSet();
            //SQL Query para obter apenas a Data de Emissão.
            string query_string = "SELECT data_emissao FROM Conta WHERE id_conta = @id_conta";
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@id_conta", SqlDbType.Int);
                command.Parameters["@id_conta"].Value = id_conta;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(command);
                data_adapter.Fill(data_set, "Conta");
                connection.Close();
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro no banco: " + ex.Message);
            }
            try
            {
                //Criação da DataTable com os dados extraídos do banco.
                DataTable data_table = data_set.Tables["Conta"];

                DataRow row = data_table.Rows[0];
                DateTime data_emissao = Convert.ToDateTime(row["data_emissao"]);
                return data_emissao.ToString();
            }
            catch
            {
                return "";
            }
        }

        public static int insertConta(double valor, string descricao, DateTime data_criacao, DateTime data_vencimento, int id_atendimento, int status)
        {
            //SQL Query que varia de acordo com o ID do Atendimento.
			int id_conta = 0;
            string query_string = "";
            if (id_atendimento == 0)
            {
                query_string = @"INSERT INTO Conta (valor, data_criacao, data_vencimento, status, descricao) 
                                   VALUES (@valor, @data_criacao, @data_vencimento, @status, @descricao)";
            }
            else
            {
                query_string = @"INSERT INTO Conta (valor, data_criacao, data_vencimento, status, id_atendimento, descricao) 
                                   VALUES (@valor, @data_criacao, @data_vencimento, @status, @id_atendimento, @descricao)";
            }
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@valor", SqlDbType.Float);
                command.Parameters.Add("@data_criacao", SqlDbType.DateTime);
                command.Parameters.Add("@data_vencimento", SqlDbType.DateTime);
                command.Parameters.Add("@status", SqlDbType.Int);
                command.Parameters.Add("@id_atendimento", SqlDbType.Int);
                command.Parameters.Add("@descricao", SqlDbType.VarChar);
                command.Parameters["@valor"].Value = valor;
                command.Parameters["@data_criacao"].Value = data_criacao;
                command.Parameters["@data_vencimento"].Value = data_vencimento;
                command.Parameters["@status"].Value = status;
                command.Parameters["@id_atendimento"].Value = id_atendimento;
                command.Parameters["@descricao"].Value = descricao;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                command.ExecuteNonQuery();

				//Recupera o ID dessa Conta.
				command.Parameters.Clear();
				command.CommandText = "SELECT @@IDENTITY";
				id_conta = Convert.ToInt32(command.ExecuteScalar());

				connection.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro no criação de uma nova Conta: " + ex.Message);
            }

			return id_conta;
        }

		public static void updateValor(int id_conta, double valor)
		{
			//SQL Query.
			string query_string = "UPDATE Conta SET valor = @valor WHERE id_conta = @id_conta";
			try
			{
				//Define os parâmetros e cria a conexão.
				SqlConnection connection = new SqlConnection(connectionSettings);
				SqlCommand command = new SqlCommand(query_string, connection);
				command.Parameters.Add("@valor", SqlDbType.Real);
				command.Parameters.Add("@id_conta", SqlDbType.Int);
				command.Parameters["@valor"].Value = valor;
				command.Parameters["@id_conta"].Value = id_conta;
				command.CommandType = CommandType.Text;

				//Executa a SQL Query.
				connection.Open();
				command.ExecuteNonQuery();
				connection.Dispose();
			}
			catch (Exception ex)
			{
				throw new Exception("Ocorreu um erro na atualização dos dados de uma Conta: " + ex.Message);
			}
		}

        public static void updateDataEmissao(int id_conta, DateTime data_emissao)
        {
            //SQL Query.
            string query_string = "UPDATE Conta SET data_emissao = @data_emissao, status = 2 WHERE id_conta = @id_conta";
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@data_emissao", SqlDbType.DateTime);
                command.Parameters.Add("@id_conta", SqlDbType.Int);
                command.Parameters["@data_emissao"].Value = data_emissao;
                command.Parameters["@id_conta"].Value = id_conta;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                command.ExecuteNonQuery();
                connection.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro na atualização dos dados de uma Conta: " + ex.Message);
            }
        }

        public static void updateDataPagamento(int id_conta, DateTime data_pagamento)
        {
            //SQL Query.
            string query_string = "UPDATE Conta SET data_pagamento = @data_pagamento, status = 1 WHERE id_conta = @id_conta";
            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection connection = new SqlConnection(connectionSettings);
                SqlCommand command = new SqlCommand(query_string, connection);
                command.Parameters.Add("@data_pagamento", SqlDbType.DateTime);
                command.Parameters.Add("@id_conta", SqlDbType.Int);
                command.Parameters["@data_pagamento"].Value = data_pagamento;
                command.Parameters["@id_conta"].Value = id_conta;
                command.CommandType = CommandType.Text;

                //Executa a SQL Query.
                connection.Open();
                command.ExecuteNonQuery();
                connection.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception("Ocorreu um erro na atualização dos dados de uma Conta: " + ex.Message);
            }
        }

		public static void updateConta(int id_conta, double valor, string descricao, DateTime data_vencimento, int id_atendimento)
		{
			//SQL Query.
			string query_string = "";
			if (id_atendimento != 0)
			{
				query_string = @"UPDATE Conta SET valor = @valor, descricao = @descricao, data_vencimento = @data_vencimento, id_atendimento = @id_atendimento WHERE id_conta = @id_conta";
			}
			else
			{
				query_string = @"UPDATE Conta SET valor = @valor, descricao = @descricao, data_vencimento = @data_vencimento WHERE id_conta = @id_conta";
			}
			try
			{
				//Define os parâmetros e cria a conexão.
				SqlConnection connection = new SqlConnection(connectionSettings);
				SqlCommand command = new SqlCommand(query_string, connection);
				command.Parameters.Add("@valor", SqlDbType.Real);
				command.Parameters.Add("@descricao", SqlDbType.VarChar);
				command.Parameters.Add("@data_vencimento", SqlDbType.DateTime);
				command.Parameters.Add("@id_conta", SqlDbType.Int);
				command.Parameters["@valor"].Value = valor;
				command.Parameters["@descricao"].Value = descricao;
				command.Parameters["@data_vencimento"].Value = data_vencimento;
				command.Parameters["@id_conta"].Value = id_conta;
				if (id_atendimento != 0)
				{
					command.Parameters.Add("@id_atendimento", SqlDbType.Int);
					command.Parameters["@id_atendimento"].Value = id_atendimento;
				}
				command.CommandType = CommandType.Text;

				//Executa a SQL Query.
				connection.Open();
				command.ExecuteNonQuery();
				connection.Dispose();
			}
			catch (Exception ex)
			{
				throw new Exception("Ocorreu um erro na atualização dos dados de uma Conta: " + ex.Message);
			}
		}


        //Retorna as contas de determinado tipo e numa faixa de data de lançamento
        public static DataTable listServicos(int idConta)
        {
            //SQL Query para obter a lista de Contas.
            string query_string = "SELECT * FROM ContaServico WHERE id_conta= @idConta";

            try
            {
                //Define os parâmetros e cria a conexão.
                SqlConnection conn = new SqlConnection(connectionSettings);
                SqlCommand cmd = new SqlCommand(query_string, conn);
                cmd.Parameters.Add("@idConta", SqlDbType.Int);
                cmd.Parameters["@idConta"].Value = idConta;
                cmd.CommandType = CommandType.Text;

                //Executa a SQL Query.
                conn.Open();
                SqlDataAdapter data_adapter = new SqlDataAdapter(cmd);
                DataSet data_set = new DataSet();
                data_adapter.Fill(data_set, "ContaServico");
                conn.Close();

                return data_set.Tables["ContaServico"];
            }
            catch (Exception ex)
            {
                throw new Exception("Erro no acesso aos dados." + ex.Message);
            }
        }

		public static int insertContaServico(int id_conta, int id_servico, string descricao, double valor)
		{
			int id_conta_servico = 0;
			//SQL Query que varia de acordo com o ID do Atendimento.
			string query_string = "INSERT INTO ContaServico (id_conta, id_servico, desc_servico, valor_servico) VALUES (@id_conta, @id_servico, @descricao, @valor)";
			try
			{
				//Define os parâmetros e cria a conexão.
				SqlConnection connection = new SqlConnection(connectionSettings);
				SqlCommand command = new SqlCommand(query_string, connection);
				command.Parameters.Add("@id_conta", SqlDbType.Int);
				command.Parameters.Add("@id_servico", SqlDbType.Int);
				command.Parameters.Add("@descricao", SqlDbType.VarChar);
				command.Parameters.Add("@valor", SqlDbType.Real);
				command.Parameters["@id_conta"].Value = id_conta;
				command.Parameters["@id_servico"].Value = id_servico;
				command.Parameters["@descricao"].Value = descricao;
				command.Parameters["@valor"].Value = valor;
				command.CommandType = CommandType.Text;

				//Executa a SQL Query.
				connection.Open();
				command.ExecuteNonQuery();

				//Recupera o ID dessa Conta.
				command.Parameters.Clear();
				command.CommandText = "SELECT @@IDENTITY";
				id_conta_servico = Convert.ToInt32(command.ExecuteScalar());

				connection.Dispose();
			}
			catch (Exception ex)
			{
				throw new Exception("Ocorreu um erro na criação de entrada em \"ContaServico\": " + ex.Message);
			}

			return id_conta_servico;
		}
    }
}
